package com.heima.wemedia.service.impl;
// 爱情不是随便许诺,算了,不想再说了

import com.fasterxml.jackson.core.type.TypeReference;
import com.heima.article.client.ArticleFeign;
import com.heima.common.aliyun.GreenImageUploadScan;
import com.heima.common.aliyun.GreenTextScan;
import com.heima.common.delayTask.RedisDelayedQueueUtil;
import com.heima.common.enums.AppHttpCodeEnum;
import com.heima.common.exception.LeadException;
import com.heima.common.util.BeanHelper;
import com.heima.common.util.JsonUtils;
import com.heima.file.service.MinioService;
import com.heima.model.media.dtos.WmNewsResultDTO;
import com.heima.wemedia.entity.WmNews;
import com.heima.wemedia.service.WmNewsAuditService;
import com.heima.wemedia.service.WmNewsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class WmNewsAuditServiceImpl implements WmNewsAuditService {

    @Autowired
    private MinioService minioService;

    @Autowired
    private WmNewsService newsService;

    @Autowired
    private GreenImageUploadScan imageUploadScan;

    @Autowired
    private GreenTextScan greenTextScan;

    @Autowired
    private ArticleFeign articleFeign;

    // 延迟队列
    @Autowired
    private RedisDelayedQueueUtil redisDelayedQueueUtil;

    /**
     * 文章审核
     *
     * @param wmNewsId
     */
    @Async  // 异步调用
    @Override
    public void auditWmNews(Integer wmNewsId) {
        // 查询自媒体文章
        WmNews wmNews = newsService.getById(wmNewsId);
        if (wmNews == null) {
            log.error("文章不存在={}", wmNewsId);
            throw new LeadException(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        // 获取文章的文字和图片
        Map<String, Object> map = getTextAndImages(wmNews);
        // 得到文字
        String text = map.get("text").toString();
        // 得到图片
        List<String> urls = (List<String>) map.get("image");
        // 调用阿里云检测文本内容
        boolean b = checkText(text, wmNewsId);
        if (!b) {
            log.error("文本审核不通过");
            return;
        }
        // 调用阿里云检测图片
        boolean b1 = checkImage(urls, wmNewsId);
        if (!b1) {
            log.error("图片审核不通过");
            return;
        }
        // 修改状态
        updateWmNewsStatus(wmNewsId,8,null,null);
        // 判断是否已到发布时间
        if (wmNews.getPublishTime() != null && wmNews.getPublishTime().getTime() > System.currentTimeMillis()) {
            // 如果没有到发布时间，把文章id写入延迟队列
            log.info("没有到发布时间，把文章id写入延迟队列");
            // 算出需要延迟多久
            long delayTime = wmNews.getPublishTime().getTime() - System.currentTimeMillis();

            redisDelayedQueueUtil.addQueue(wmNewsId,delayTime, TimeUnit.MILLISECONDS,"wm.news.pub");

            return;
        }

        publisWmNews(wmNewsId, wmNews);

    }

    /**
     * 发布文章
     * @param wmNewsId 必传
     * @param wmNews 可以不传
     */
    public  void publisWmNews(Integer wmNewsId, WmNews wmNews) {
        // 需要远程调用 article 服务 ,保存文章
        WmNewsResultDTO resultDTO = BeanHelper.copyProperties(wmNews, WmNewsResultDTO.class);
        try {
            Long apAritlceId = articleFeign.saveArticle(resultDTO);
            // 修改文章状态,已发布 9
            updateWmNewsStatus(wmNewsId, 9, null, apAritlceId);
        } catch (Exception e) {
            log.error("远程调用发布文章失败!");
            e.printStackTrace();
            throw new LeadException(AppHttpCodeEnum.SERVER_ERROR);
        }
    }

    /**
     * 检测图片内容
     *
     * @param urls
     * @param wmNewsId
     * @return
     */
    private boolean checkImage(List<String> urls, Integer wmNewsId) {
        List<byte[]> imageBytes = new ArrayList<>();
        // 从minIO下载图片
        for (String url : urls) {
            byte[] bytes = minioService.downLoadFile(url);
            imageBytes.add(bytes);
        }
        // 上传到阿里云检测
        try {
            Map<String, String> map = imageUploadScan.imageScan(imageBytes);
            String suggestion = map.get("suggestion");
            // 审核原因
            String label = map.get("label");
            if (suggestion.equals("pass")) {
                // 检测通过
                log.info("阿里云图片审核 返回pass");
                return true;
            } else if ("review".equals(suggestion)) {
                log.info("阿里云图片审核 返回 review");
                // 人工审核,修改文章状态 3
                updateWmNewsStatus(wmNewsId, 3, label, null);
                return false;
            } else {
                log.info("阿里云图片审核 返回 block");
                // 审核不通过,修改文章状态 2
                updateWmNewsStatus(wmNewsId, 2, label, null);
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 调用阿里云文本检测接口
     *
     * @param text
     */
    private boolean checkText(String text, Integer wmNewsId) {
        try {
            Map<String, String> map = greenTextScan.greenTextScan(text);
            String suggestion = map.get("suggestion");
            // 审核原因
            String reason = map.get("reason");
            if (suggestion.equals("pass")) {
                // 检测通过
                log.info("阿里云审核 返回pass");
                return true;
            } else if ("review".equals(suggestion)) {
                log.info("阿里云审核 返回 review");
                // 人工审核,修改文章状态 3
                updateWmNewsStatus(wmNewsId, 3, reason, null);
                return false;
            } else {
                // 审核不通过,修改文章状态 2
                log.info("阿里云审核 返回 block");
                updateWmNewsStatus(wmNewsId, 2, reason, null);
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }

    }

    /**
     * 修改文章状态
     *
     * @param wmNewsId 修改文章id
     * @param status   修改的状态
     * @param reason   修改的原因
     */
    private void updateWmNewsStatus(Integer wmNewsId, Integer status, String reason, Long apAritlceId) {
        WmNews wmNews = new WmNews();
        wmNews.setId(wmNewsId);
        wmNews.setStatus(status);
        wmNews.setReason(reason);

        if (apAritlceId != null) {
            wmNews.setArticleId(apAritlceId);
        }
        newsService.updateById(wmNews);
    }

    private Map<String, Object> getTextAndImages(WmNews wmNews) {
        // 存放图片的路径 --(内容,封面)
        List<String> urls = new ArrayList<>();

        // 提取文字,包含title,content的text内容
        StringBuilder sbr = new StringBuilder();
        sbr.append(wmNews.getTitle());
        // 获得传递的数据json数据
        String content = wmNews.getContent();
        // json转list
        List<Map<String, Object>> list = JsonUtils.nativeRead(content, new TypeReference<List<Map<String, Object>>>() {
        });

        for (Map<String, Object> map : list) {
            // 得到值
            String type = map.get("type").toString();
            String value = map.get("value").toString();
            // 保存文字
            if (type.equals("text")) {
                sbr.append(value);
            } else {
                urls.add(value);
            }
        }
        if (StringUtils.isEmpty(wmNews.getImages())) {
            urls.addAll(Arrays.asList(wmNews.getImages()));
        }
        Map<String, Object> map = new HashMap<>();
        map.put("text", sbr.toString());
        map.put("image", urls);
        return map;
    }
}
